home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gdb-4.5 / dist / gdb / expprint.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-03  |  11.4 KB  |  407 lines

  1. /* Print in infix form a struct expression.
  2.    Copyright (C) 1986, 1989, 1991 Free Software Foundation, Inc.
  3.  
  4. This file is part of GDB.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "defs.h"
  21. #include "symtab.h"
  22. #include "gdbtypes.h"
  23. #include "expression.h"
  24. #include "value.h"
  25. #include "language.h"
  26. #include "parser-defs.h"
  27.  
  28. /* Prototypes for local functions */
  29.  
  30. static void
  31. print_subexp PARAMS ((struct expression *, int *, FILE *, enum precedence));
  32.  
  33. static void
  34. print_simple_m2_func PARAMS ((char *, struct expression *, int *, FILE *));
  35.  
  36. void
  37. print_expression (exp, stream)
  38.      struct expression *exp;
  39.      FILE *stream;
  40. {
  41.   int pc = 0;
  42.   print_subexp (exp, &pc, stream, PREC_NULL);
  43. }
  44.  
  45. /* Print the subexpression of EXP that starts in position POS, on STREAM.
  46.    PREC is the precedence of the surrounding operator;
  47.    if the precedence of the main operator of this subexpression is less,
  48.    parentheses are needed here.  */
  49.  
  50. static void
  51. print_subexp (exp, pos, stream, prec)
  52.      register struct expression *exp;
  53.      register int *pos;
  54.      FILE *stream;
  55.      enum precedence prec;
  56. {
  57.   register unsigned tem;
  58.   register const struct op_print *op_print_tab;
  59.   register int pc;
  60.   unsigned nargs;
  61.   register char *op_str;
  62.   int assign_modify = 0;
  63.   enum exp_opcode opcode;
  64.   enum precedence myprec;
  65.   /* Set to 1 for a right-associative operator.  */
  66.   int assoc;
  67.   value val;
  68.  
  69.   op_print_tab = exp->language_defn->la_op_print_tab;
  70.   pc = (*pos)++;
  71.   opcode = exp->elts[pc].opcode;
  72.   switch (opcode)
  73.     {
  74.     /* Common ops */
  75.  
  76.     case OP_SCOPE:
  77.       myprec = PREC_PREFIX;
  78.       assoc = 0;
  79.       (*pos) += 2;
  80.       print_subexp (exp, pos, stream,
  81.             (enum precedence) ((int) myprec + assoc));
  82.       fputs_filtered (" :: ", stream);
  83.       nargs = strlen (&exp->elts[pc + 2].string);
  84.       (*pos) += 1 + (nargs + sizeof (union exp_element)) / sizeof (union exp_element);
  85.  
  86.       fputs_filtered (&exp->elts[pc + 2].string, stream);
  87.       return;
  88.  
  89.     case OP_LONG:
  90.       (*pos) += 3;
  91.       value_print (value_from_longest (exp->elts[pc + 1].type,
  92.                     exp->elts[pc + 2].longconst),
  93.            stream, 0, Val_no_prettyprint);
  94.       return;
  95.  
  96.     case OP_DOUBLE:
  97.       (*pos) += 3;
  98.       value_print (value_from_double (exp->elts[pc + 1].type,
  99.                       exp->elts[pc + 2].doubleconst),
  100.            stream, 0, Val_no_prettyprint);
  101.       return;
  102.  
  103.     case OP_VAR_VALUE:
  104.       (*pos) += 2;
  105.       fputs_filtered (SYMBOL_NAME (exp->elts[pc + 1].symbol), stream);
  106.       return;
  107.  
  108.     case OP_LAST:
  109.       (*pos) += 2;
  110.       fprintf_filtered (stream, "$%d",
  111.             longest_to_int (exp->elts[pc + 1].longconst));
  112.       return;
  113.  
  114.     case OP_REGISTER:
  115.       (*pos) += 2;
  116.       fprintf_filtered (stream, "$%s",
  117.            longest_to_int (reg_names[exp->elts[pc + 1].longconst]));
  118.       return;
  119.  
  120.     case OP_INTERNALVAR:
  121.       (*pos) += 2;
  122.       fprintf_filtered (stream, "$%s",
  123.            internalvar_name (exp->elts[pc + 1].internalvar));
  124.       return;
  125.  
  126.     case OP_FUNCALL:
  127.       (*pos) += 2;
  128.       nargs = longest_to_int (exp->elts[pc + 1].longconst);
  129.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  130.       fputs_filtered (" (", stream);
  131.       for (tem = 0; tem < nargs; tem++)
  132.     {
  133.       if (tem != 0)
  134.         fputs_filtered (", ", stream);
  135.       print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
  136.     }
  137.       fputs_filtered (")", stream);
  138.       return;
  139.  
  140.     case OP_STRING:
  141.       nargs = strlen (&exp->elts[pc + 1].string);
  142.       (*pos) += 2 + (nargs + sizeof (union exp_element)) / sizeof (union exp_element);
  143.       fputs_filtered ("\"", stream);
  144.       for (tem = 0; tem < nargs; tem++)
  145.     printchar ((&exp->elts[pc + 1].string)[tem], stream, '"');
  146.       fputs_filtered ("\"", stream);
  147.       return;
  148.  
  149.     case TERNOP_COND:
  150.       if ((int) prec > (int) PREC_COMMA)
  151.     fputs_filtered ("(", stream);
  152.       /* Print the subexpressions, forcing parentheses
  153.      around any binary operations within them.
  154.      This is more parentheses than are strictly necessary,
  155.      but it looks clearer.  */
  156.       print_subexp (exp, pos, stream, PREC_HYPER);
  157.       fputs_filtered (" ? ", stream);
  158.       print_subexp (exp, pos, stream, PREC_HYPER);
  159.       fputs_filtered (" : ", stream);
  160.       print_subexp (exp, pos, stream, PREC_HYPER);
  161.       if ((int) prec > (int) PREC_COMMA)
  162.     fputs_filtered (")", stream);
  163.       return;
  164.  
  165.     case STRUCTOP_STRUCT:
  166.       tem = strlen (&exp->elts[pc + 1].string);
  167.       (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
  168.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  169.       fputs_filtered (".", stream);
  170.       fputs_filtered (&exp->elts[pc + 1].string, stream);
  171.       return;
  172.  
  173.     /* Will not occur for Modula-2 */
  174.     case STRUCTOP_PTR:
  175.       tem = strlen (&exp->elts[pc + 1].string);
  176.       (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
  177.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  178.       fputs_filtered ("->", stream);
  179.       fputs_filtered (&exp->elts[pc + 1].string, stream);
  180.       return;
  181.  
  182.     case BINOP_SUBSCRIPT:
  183.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  184.       fputs_filtered ("[", stream);
  185.       print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
  186.       fputs_filtered ("]", stream);
  187.       return;
  188.  
  189.     case UNOP_POSTINCREMENT:
  190.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  191.       fputs_filtered ("++", stream);
  192.       return;
  193.  
  194.     case UNOP_POSTDECREMENT:
  195.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  196.       fputs_filtered ("--", stream);
  197.       return;
  198.  
  199.     case UNOP_CAST:
  200.       (*pos) += 2;
  201.       if ((int) prec > (int) PREC_PREFIX)
  202.         fputs_filtered ("(", stream);
  203.       fputs_filtered ("(", stream);
  204.       type_print (exp->elts[pc + 1].type, "", stream, 0);
  205.       fputs_filtered (") ", stream);
  206.       print_subexp (exp, pos, stream, PREC_PREFIX);
  207.       if ((int) prec > (int) PREC_PREFIX)
  208.         fputs_filtered (")", stream);
  209.       return;
  210.  
  211.     case UNOP_MEMVAL:
  212.       (*pos) += 2;
  213.       if ((int) prec > (int) PREC_PREFIX)
  214.         fputs_filtered ("(", stream);
  215.       if (exp->elts[pc + 1].type->code == TYPE_CODE_FUNC &&
  216.       exp->elts[pc + 3].opcode == OP_LONG) {
  217.     /* We have a minimal symbol fn, probably.  It's encoded
  218.        as a UNOP_MEMVAL (function-type) of an OP_LONG (int, address).
  219.        Swallow the OP_LONG (including both its opcodes); ignore
  220.        its type; print the value in the type of the MEMVAL.  */
  221.     (*pos) += 4;
  222.     val = value_at_lazy (exp->elts[pc + 1].type,
  223.                  (CORE_ADDR) exp->elts[pc + 5].longconst);
  224.     value_print (val, stream, 0, Val_no_prettyprint);
  225.       } else {
  226.     fputs_filtered ("{", stream);
  227.     type_print (exp->elts[pc + 1].type, "", stream, 0);
  228.     fputs_filtered ("} ", stream);
  229.         print_subexp (exp, pos, stream, PREC_PREFIX);
  230.       }
  231.       if ((int) prec > (int) PREC_PREFIX)
  232.         fputs_filtered (")", stream);
  233.       return;
  234.  
  235.     case BINOP_ASSIGN_MODIFY:
  236.       opcode = exp->elts[pc + 1].opcode;
  237.       (*pos) += 2;
  238.       myprec = PREC_ASSIGN;
  239.       assoc = 1;
  240.       assign_modify = 1;
  241.       op_str = "???";
  242.       for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++)
  243.     if (op_print_tab[tem].opcode == opcode)
  244.       {
  245.         op_str = op_print_tab[tem].string;
  246.         break;
  247.       }
  248.       break;
  249.  
  250.     /* C++ ops */
  251.  
  252.     case OP_THIS:
  253.       ++(*pos);
  254.       fputs_filtered ("this", stream);
  255.       return;
  256.  
  257.     /* Modula-2 ops */
  258.  
  259.     case BINOP_MULTI_SUBSCRIPT:
  260.       (*pos) += 2;
  261.       nargs = longest_to_int (exp->elts[pc + 1].longconst);
  262.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  263.       fprintf (stream, " [");
  264.       for (tem = 0; tem < nargs; tem++)
  265.     {
  266.       if (tem != 0)
  267.         fprintf (stream, ", ");
  268.       print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
  269.     }
  270.       fprintf (stream, "]");
  271.       return;
  272.  
  273.     case BINOP_VAL:
  274.       (*pos)+=2;
  275.       fprintf(stream,"VAL(");
  276.       type_print(exp->elts[pc+1].type,"",stream,0);
  277.       fprintf(stream,",");
  278.       print_subexp(exp,pos,stream,PREC_PREFIX);
  279.       fprintf(stream,")");
  280.       return;
  281.  
  282.     case UNOP_CAP:
  283.       print_simple_m2_func("CAP",exp,pos,stream);
  284.       return;
  285.  
  286.     case UNOP_CHR:
  287.       print_simple_m2_func("CHR",exp,pos,stream);
  288.       return;
  289.  
  290.     case UNOP_ORD:
  291.       print_simple_m2_func("ORD",exp,pos,stream);
  292.       return;
  293.       
  294.     case UNOP_ABS:
  295.       print_simple_m2_func("ABS",exp,pos,stream);
  296.       return;
  297.  
  298.     case UNOP_FLOAT:
  299.       print_simple_m2_func("FLOAT",exp,pos,stream);
  300.       return;
  301.  
  302.     case UNOP_HIGH:
  303.       print_simple_m2_func("HIGH",exp,pos,stream);
  304.       return;
  305.  
  306.     case UNOP_MAX:
  307.       print_simple_m2_func("MAX",exp,pos,stream);
  308.       return;
  309.  
  310.     case UNOP_MIN:
  311.       print_simple_m2_func("MIN",exp,pos,stream);
  312.       return;
  313.  
  314.     case UNOP_ODD:
  315.       print_simple_m2_func("ODD",exp,pos,stream);
  316.       return;
  317.  
  318.     case UNOP_TRUNC:
  319.       print_simple_m2_func("TRUNC",exp,pos,stream);
  320.       return;
  321.       
  322.     case BINOP_INCL:
  323.     case BINOP_EXCL:
  324.       error("print_subexp:  Not implemented.");
  325.  
  326.     /* Default ops */
  327.  
  328.     default:
  329.       op_str = "???";
  330.       for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++)
  331.     if (op_print_tab[tem].opcode == opcode)
  332.       {
  333.         op_str = op_print_tab[tem].string;
  334.         myprec = op_print_tab[tem].precedence;
  335.         assoc = op_print_tab[tem].right_assoc;
  336.         break;
  337.       }
  338.    }
  339.  
  340.   if ((int) myprec < (int) prec)
  341.     fputs_filtered ("(", stream);
  342.   if ((int) opcode > (int) BINOP_END)
  343.     {
  344.       /* Unary prefix operator.  */
  345.       fputs_filtered (op_str, stream);
  346.       print_subexp (exp, pos, stream, PREC_PREFIX);
  347.     }
  348.   else
  349.     {
  350.       /* Binary operator.  */
  351.       /* Print left operand.
  352.      If operator is right-associative,
  353.      increment precedence for this operand.  */
  354.       print_subexp (exp, pos, stream,
  355.             (enum precedence) ((int) myprec + assoc));
  356.       /* Print the operator itself.  */
  357.       if (assign_modify)
  358.     fprintf_filtered (stream, " %s= ", op_str);
  359.       else if (op_str[0] == ',')
  360.     fprintf_filtered (stream, "%s ", op_str);
  361.       else
  362.     fprintf_filtered (stream, " %s ", op_str);
  363.       /* Print right operand.
  364.      If operator is left-associative,
  365.      increment precedence for this operand.  */
  366.       print_subexp (exp, pos, stream,
  367.             (enum precedence) ((int) myprec + !assoc));
  368.     }
  369.  
  370.   if ((int) myprec < (int) prec)
  371.     fputs_filtered (")", stream);
  372. }
  373.  
  374. /* Print out something of the form <s>(<arg>).
  375.    This is used to print out some builtin Modula-2
  376.    functions.
  377.    FIXME:  There is probably some way to get the precedence
  378.    rules to do this (print a unary operand with parens around it).  */
  379. static void
  380. print_simple_m2_func(s,exp,pos,stream)
  381.    char *s;
  382.    register struct expression *exp;
  383.    register int *pos;
  384.    FILE *stream;
  385. {
  386.    fprintf(stream,"%s(",s);
  387.    print_subexp(exp,pos,stream,PREC_PREFIX);
  388.    fprintf(stream,")");
  389. }
  390.    
  391. /* Return the operator corresponding to opcode OP as
  392.    a string.   NULL indicates that the opcode was not found in the
  393.    current language table.  */
  394. char *
  395. op_string(op)
  396.    enum exp_opcode op;
  397. {
  398.   int tem;
  399.   register const struct op_print *op_print_tab;
  400.  
  401.   op_print_tab = current_language->la_op_print_tab;
  402.   for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++)
  403.     if (op_print_tab[tem].opcode == op)
  404.       return op_print_tab[tem].string;
  405.   return NULL;
  406. }
  407.